﻿#include "WRWorkTcpCommDomain.h"
#include "Runtime/WRWorkDomainActivator.h"
#include "../WRSoft-Utility/WRConfig.h"
#include "../WRSoft-Utility/Runtime/WRClass.h"
#include "Clients/WRWorkTcpCommClientRoutine.h"
#include "Clients/WRWorkTcpCommClientContext.h"
#include "WRWorkSwitchEvent.h"

#include <QSemaphore>
#include <QCoreApplication>

//表示工作TCP通讯域激活器。
class WRWorkTcpCommDomainActivator : public WRWorkDomainActivator
{
public:
    //初始化工作TCP通讯域激活器。
    WRWorkTcpCommDomainActivator(void)
    {
        QChar className[] = WRWorkTcpCommDomainStrArr;
        WRClass::enroll(WRWorkTcpCommDomainClass, QString(className, WRWorkTcpCommDomainStrLen), this);
    }
    //清理当前对象所占用的相关资源。
    ~WRWorkTcpCommDomainActivator(void)
    {
        //add code here
    }

    //创建工作域实例。
    WRWorkDomain* create(WRWorkDaemon* daemon, const QDomElement& config)
    {
        QChar addrLiteral[] = {'a', 'd', 'd', 'r'};
        QString addrString = QString::fromRawData(addrLiteral, 4);
        QChar portLiteral[] = {'p', 'o', 'r', 't'};
        QString portString = QString::fromRawData(portLiteral, 4);
        QChar autostartLiteral[] = {'a', 'u', 't', 'o', 's', 't', 'a', 'r', 't'};
        QString autostartString = QString::fromRawData(autostartLiteral, 9);

        QString text = WRConfig::readValue(config, addrString);
        if (text.isNull() || text.isEmpty())
        {
            return 0;
        }
        QHostAddress addr(text);
        if (addr.isNull())
        {
            return 0;
        }

        text = WRConfig::readValue(config, portString);
        if (text.isNull() || text.isEmpty())
        {
            return 0;
        }
        bool result = false;
        int port = text.toInt(&result);
        if (!result || port < 0 || port > 32768)
        {
            return 0;
        }

        bool autostart = true;
        text = WRConfig::readValue(config, autostartString);
        QChar falseLiteral[] = {'F', 'A', 'L', 'S', 'E'};
        QString falseString = QString::fromRawData(falseLiteral, 5);
        if (text.compare(falseString, Qt::CaseInsensitive) == 0)
        {
            autostart = false;
        }

        WRWorkInformation info;
        if (!info.create(config))
        {
            return 0;
        }

        return new WRWorkTcpCommDomain(info, daemon, addr, (WR16u)port, autostart);
    }
};
//唯一实例。
static WRWorkTcpCommDomainActivator g_workTcpCommDomainActivator;

//上下文对象。
WRWorkTcpCommClientContext* WRWorkTcpCommDomain::_ctx = 0;

//初始化TCP通讯域。
WRWorkTcpCommDomain::WRWorkTcpCommDomain(const WRWorkInformation& info, WRWorkDaemon* daemon, const QHostAddress& addr, WR16u port, bool autostart)
    : WRWorkDomain(info, daemon), m_addr(addr)
{
    if (!_ctx)
    {
        _ctx = new WRWorkTcpCommClientContext();
    }
    else
    {
        _ctx->addRef();
    }

    m_port = port;
    m_autostart = autostart;

    m_routine = new WRWorkTcpCommClientRoutine(this);
    m_routine->moveToThread(_ctx->thread());
}
//清理当前对象所占用的相关资源。
WRWorkTcpCommDomain::~WRWorkTcpCommDomain()
{
    m_routine->deleteLater();
    if (_ctx->release())
    {
        _ctx = 0;
    }
}

//当加载后执行相应的初始工作。
void WRWorkTcpCommDomain::onInit(void)
{
    WRWorkDomain::onInit();
    if (m_autostart)
    {
        start();
    }
}
//当删除前执行相应的清理工作。
void WRWorkTcpCommDomain::onFree(void)
{
    close();
    WRWorkDomain::onFree();
}

//启动工作域。
bool WRWorkTcpCommDomain::start(void)
{
    QSemaphore mutex;
    bool result = false;
    QCoreApplication::postEvent(m_routine, new WRWorkSwitchEvent(&mutex, WRWorkSwitchEvent::Start, 0, &result));
    mutex.acquire();
    return result;
}
//关闭工作域。
void WRWorkTcpCommDomain::close(void)
{
    QSemaphore mutex;
    QCoreApplication::postEvent(m_routine, new WRWorkSwitchEvent(&mutex, WRWorkSwitchEvent::Close, 0, 0));
    mutex.acquire();
}
